package com.link.base.core.basic.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Objects;

public class BigDecimalUtils {
    public static BigDecimal changeNullToZero(BigDecimal number) throws Exception {
        if (number == null) {
            return BigDecimal.ZERO;
        }
        return number;
    }

    /**
     * 除法
     */
    public static BigDecimal divide(BigDecimal arg1, BigDecimal arg2) {
        if (Objects.isNull(arg1)) {
            arg1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(arg2)) {
            arg2 = BigDecimal.ZERO;
        }
        return arg1.divide(arg2, 6, RoundingMode.HALF_UP);
    }

    /**
     * 除法
     */
    public static BigDecimal divideScale(BigDecimal arg1, BigDecimal arg2, int scale) {
        if (Objects.isNull(arg1)) {
            arg1 = BigDecimal.ZERO.setScale(scale);
        }
        if (Objects.isNull(arg2) || BigDecimal.ZERO.compareTo(arg2) == 0) {
            return BigDecimal.ZERO.setScale(scale);
        }
        return arg1.divide(arg2, scale, RoundingMode.HALF_UP);
    }

    /**
     * 乘法
     */
    public static BigDecimal multiply(BigDecimal arg1, BigDecimal arg2) {
        if (Objects.isNull(arg1)) {
            arg1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(arg2)) {
            arg2 = BigDecimal.ZERO;
        }
        return arg1.multiply(arg2);
    }

    /**
     * 减法
     */
    public static BigDecimal subtract(BigDecimal arg1, BigDecimal arg2) {
        if (Objects.isNull(arg1)) {
            arg1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(arg2)) {
            arg2 = BigDecimal.ZERO;
        }
        return arg1.subtract(arg2);
    }

    /**
     * 加法
     */
    public static BigDecimal add(BigDecimal arg1, BigDecimal arg2) {
        if (Objects.isNull(arg1)) {
            arg1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(arg2)) {
            arg2 = BigDecimal.ZERO;
        }
        return arg1.add(arg2);
    }


    /**
     * 四舍五入保留N位小数
     *
     * @param arg   入参
     * @param scare 保留位数
     */
    public static BigDecimal setScare(BigDecimal arg, int scare) {
        if (Objects.isNull(arg)) {
            return BigDecimal.ZERO;
        }
        return arg.setScale(scare, RoundingMode.HALF_UP);
    }


    /**
     * 四舍五入保留两位小数 先四舍五入在使用double值自动去零
     *
     * @param arg 入参
     */
    public static BigDecimal setTwoScare(BigDecimal arg) {
        if (Objects.isNull(arg)) {
            return BigDecimal.ZERO;
        }
        return arg.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 如果value为null,则转换为 0
     *
     * @param value 入参
     */
    public static BigDecimal nullToZero(BigDecimal value) {
        if (null == value) {
            return BigDecimal.ZERO;
        }
        return value;
    }

    /**
     * 如果value为null,则转换为 1
     *
     * @param value 入参
     */
    public static BigDecimal nullToOne(BigDecimal value) {
        if (null == value) {
            return BigDecimal.valueOf(1);
        }
        return value;
    }

    /**
     * 判断是否为0
     *
     * @param money 入参
     */
    public static boolean isZero(BigDecimal money) {
        if (null == money) {
            money = BigDecimal.ZERO;
        }
        return BigDecimal.ZERO.compareTo(money) == 0;
    }

    /**
     * 大于0
     */
    public static boolean greaterThanZero(BigDecimal value) {
        if (value == null) {
            return false;
        }
        return value.compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * 大于等于0
     */
    public static boolean greaterThanIsZero(BigDecimal value) {
        if (value == null) {
            return false;
        }
        return value.compareTo(BigDecimal.ZERO) >= 0;
    }

    /**
     * 小于0
     */
    public static boolean lessThanZero(BigDecimal value) {
        if (value == null) {
            return false;
        }
        return value.compareTo(BigDecimal.ZERO) < 0;
    }

    /**
     * v1 > v2
     */
    public static boolean greater(BigDecimal v1, BigDecimal v2) {
        if (Objects.isNull(v1)) {
            v1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(v2)) {
            v2 = BigDecimal.ZERO;
        }
        return v1.compareTo(v2) > 0;
    }

    /**
     * v1 >= v2
     */
    public static boolean greaterEquals(BigDecimal v1, BigDecimal v2) {
        if (Objects.isNull(v1)) {
            v1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(v2)) {
            v2 = BigDecimal.ZERO;
        }
        return v1.compareTo(v2) >= 0;
    }

    /**
     * v1 < v2
     */
    public static boolean less(BigDecimal v1, BigDecimal v2) {
        if (Objects.isNull(v1)) {
            v1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(v2)) {
            v2 = BigDecimal.ZERO;
        }
        return v1.compareTo(v2) < 0;
    }

    /**
     * v1 = v2
     */
    public static boolean equals(BigDecimal v1, BigDecimal v2) {
        if (Objects.isNull(v1)) {
            v1 = BigDecimal.ZERO;
        }
        if (Objects.isNull(v2)) {
            v2 = BigDecimal.ZERO;
        }
        return v1.compareTo(v2) == 0;
    }

    /**
     * 返回小数的位数
     *
     * @param bigDecimal 入参
     * @return int
     */
    public static int getNumber(BigDecimal bigDecimal) {
        if (Objects.isNull(bigDecimal)) {
            return 0;
        }
        String string = bigDecimal.stripTrailingZeros().toPlainString();
        int index = string.indexOf(".");
        return index < 0 ? 0 : string.length() - index - 1;
    }

    /**
     * 判断是否整除
     *
     * @return boolean
     */
    public static boolean divisible(BigDecimal arg1, BigDecimal arg2) {
        if (Objects.isNull(arg1)) {
            return false;
        }
        if (Objects.isNull(arg2)) {
            return false;
        }
        BigDecimal bigDecimal = divide(arg1, arg2);
        String string = bigDecimal.stripTrailingZeros().toPlainString();
        int index = string.indexOf(".");
        return index < 0 ? Boolean.TRUE : Boolean.FALSE;
    }

    /**
     * Double 转 BigDecimal
     */
    public static BigDecimal valueDoubleOf(Double v1) {
        if (Objects.isNull(v1)) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(v1);
    }

    /**
     * String 转 BigDecimal
     */
    public static BigDecimal valueStringOf(String v1) {
        if (Objects.isNull(v1)) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(Double.parseDouble(v1));
    }

    /**
     * 取相反值
     */
    public static BigDecimal negate(BigDecimal v1) {
        if (Objects.isNull(v1)) {
            return BigDecimal.ZERO;
        }
        if (isZero(v1)) {
            return BigDecimal.ZERO;
        }
        return v1.negate();
    }

    /**
     * 绝对值
     */
    public static BigDecimal abs(BigDecimal v1) {
        if (Objects.isNull(v1)) {
            return BigDecimal.ZERO;
        }
        if (isZero(v1)) {
            return BigDecimal.ZERO;
        }
        return v1.abs();
    }

    /**
     * 除100
     */
    public static BigDecimal divideOneHundred(BigDecimal arg1) {
        if (Objects.isNull(arg1)) {
            return BigDecimal.ZERO;
        }
        BigDecimal oneHundred = new BigDecimal("100");
        return arg1.divide(oneHundred, 6, RoundingMode.HALF_UP);
    }



    /**
     * 处理自动补足7位小数
     * @param arg1 数量
     */
    public static BigDecimal setScale(BigDecimal arg1) {
        if (new BigDecimal(arg1.intValue()).compareTo(arg1) == 0) {
            DecimalFormat df = new DecimalFormat("##.00");
            return new BigDecimal(df.format(arg1));
        } else {
            arg1.setScale(2, BigDecimal.ROUND_UP);
        }
        return arg1;
    }

}
